home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 2: Applications
/
Linux Cubed Series 2 - Applications.iso
/
circuits
/
irsim-ca.2
/
irsim-ca
/
irsim-cap-9.2
/
src
/
ana11
/
scrollbar.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-15
|
10KB
|
391 lines
/*
* *********************************************************************
* * Copyright (C) 1988, 1990 Stanford University. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. Stanford University *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*/
/*
* Scrollbar manager.
*/
#include "ana.h"
#include "ana_glob.h"
#include "graphics.h"
public
#define SCROLLBARHEIGHT 16
public
#define ARROW_WIDTH 32
private void StretchLeft(), StretchRight(), MoveBar();
private void MoveLeft(), MoveRight();
public void DrawScrollBar( isExpose )
int isExpose;
{
static Coord lastLeft = 0;
static Coord lastRight = 0;
if( isExpose or (scrollBox.left > lastLeft) )
FillAREA( window, 0, scrollBox.top, scrollBox.left, SCROLLBARHEIGHT,
gcs.white );
if( isExpose or (scrollBox.right < lastRight) )
FillAREA( window, scrollBox.right, scrollBox.top,
XWINDOWSIZE - scrollBox.right, SCROLLBARHEIGHT, gcs.white );
HLine( window, textBox.left, textBox.right, textBox.top, gcs.black );
lastLeft = scrollBox.left;
lastRight = scrollBox.right;
XCopyArea( display, pix.left_arrows, window, gcs.black, 0, 0, ARROW_WIDTH,
SCROLLBARHEIGHT, scrollBox.left, scrollBox.top );
XCopyArea( display, pix.right_arrows, window, gcs.black, 0, 0, ARROW_WIDTH,
SCROLLBARHEIGHT, scrollBox.right - ARROW_WIDTH, scrollBox.top );
UpdateScrollBar();
}
/*
* Update and redraw the scrollbar.
*/
public void UpdateScrollBar()
{
float tmp;
if( tims.last == tims.first )
{
barPos.left = traceBox.left;
barPos.right = traceBox.right;
}
else
{
TimeType maxTime;
maxTime = max( tims.last, tims.end );
tmp = (float)(traceBox.right - traceBox.left) / (maxTime-tims.first);
barPos.left = traceBox.left + round( tmp * (tims.start-tims.first) );
barPos.right = barPos.left + round( tmp * tims.steps );
if( barPos.right - barPos.left < 3 )
{
if( barPos.left + 3 > traceBox.right )
barPos.left = barPos.right - 3;
else
barPos.right = barPos.left + 3;
}
}
FillAREA( window, traceBox.left + 1, scrollBox.top + 1,
traceBox.right - traceBox.left - 1, SCROLLBARHEIGHT - 2, gcs.gray );
VLine( window, traceBox.left, scrollBox.bot, scrollBox.top, gcs.black );
VLine( window, traceBox.right, scrollBox.bot, scrollBox.top, gcs.black );
FillBox( window, barPos, gcs.white );
OutlineBox( window, barPos, gcs.black );
}
/*
* Handle button clicks within the scrollbar.
*/
public void DoScrollBar( ev )
XButtonEvent *ev;
{
TimeType oldStart, oldSteps;
if( (ev->x < scrollBox.left) or (ev->x > scrollBox.right) )
return;
if( ev->x < scrollBox.left + (ARROW_WIDTH / 2 - 1) )
MoveLeft( 2 );
else if( ev->x < traceBox.left )
MoveLeft( 1 );
else if( ev->x <= traceBox.right )
{
oldStart = tims.start;
oldSteps = tims.steps;
switch( ev->button & (Button1 | Button2 | Button3) )
{
case Button1 :
StretchLeft( ev->x );
break;
case Button2 :
MoveBar( ev->x );
break;
case Button3 :
StretchRight( ev->x );
break;
}
UpdateScrollBar();
if( (oldStart != tims.start) or (oldSteps != tims.steps) )
{
DrawTraces( tims.start, tims.end );
RedrawTimes();
}
}
else if( ev->x < scrollBox.right - (ARROW_WIDTH / 2 - 1) )
{
MoveRight( 1 );
}
else /* ( x < scrol.right ) */
MoveRight( 2 );
}
/*
* Stretch the scroll bar to the left, up to the current right side.
*/
private void StretchLeft( x )
Coord x;
{
Coord xmax;
XEvent ev;
float tmp;
TimeType maxTime, ti;
BBox b;
maxTime = max( tims.last, tims.end );
if( maxTime <= tims.first )
return;
tmp = (float)(maxTime - tims.first) / (traceBox.right - traceBox.left);
xmax = barPos.right - max( 3, round( 10.0 / tmp ) );
b.top = barPos.top + 1;
b.bot = barPos.bot - 1;
b.left = barPos.left;
b.right = barPos.right - 1;
FillBox( window, b, gcs.gray );
b.left = min( x, xmax );
FillBox( window, b, gcs.white );
GrabMouse( window, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
None );
UpdateTimes( tims.start, tims.end ); /* initialize it */
do
{
XNextEvent( display, &ev );
if( ev.type == MotionNotify )
x = ev.xmotion.x;
else if( ev.type == ButtonRelease )
x = ev.xbutton.x;
else
continue;
FillBox( window, b, gcs.gray );
if( x < traceBox.left )
b.left = traceBox.left;
else if( x > xmax )
b.left = xmax;
else
b.left = x;
FillBox( window, b, gcs.white );
ti = tims.first + round( (b.left - traceBox.left) * tmp );
UpdateTimes( ti, tims.end );
}
while( ev.type != ButtonRelease );
XUngrabPointer( display, CurrentTime );
XFlush( display );
barPos.left = b.left;
tims.start = tims.first + round( (b.left - traceBox.left) * tmp );
tims.steps = tims.end - tims.start;
}
/*
* Stretch the scroll bar to the right, up to the current left side.
*/
private void StretchRight( x )
Coord x;
{
Coord xmin;
XEvent ev;
float tmp;
TimeType maxTime, ti;
BBox b;
maxTime = max( tims.last, tims.end );
if( maxTime <= tims.first )
return;
tmp = (float)(maxTime - tims.first) / (traceBox.right - traceBox.left);
xmin = barPos.left + max( 3, round( 10.0/tmp ) );
b.top = barPos.top + 1;
b.bot = barPos.bot - 1;
b.left = barPos.left + 1;
b.right = barPos.right;
FillBox( window, b, gcs.gray );
b.right = max( x, xmin );
FillBox( window, b, gcs.white );
GrabMouse( window, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
None );
UpdateTimes( tims.start, tims.end ); /* initialize it */
do
{
XNextEvent( display, &ev );
if( ev.type == MotionNotify )
x = ev.xmotion.x;
else if( ev.type == ButtonRelease )
x = ev.xbutton.x;
else
continue;
FillBox( window, b, gcs.gray );
if( x < xmin )
b.right = xmin;
else if( x > traceBox.right )
b.right = traceBox.right;
else
b.right = x;
FillBox( window, b, gcs.white );
ti = tims.first + round( (b.right - traceBox.left) * tmp );
UpdateTimes( tims.start, ti );
}
while( ev.type != ButtonRelease );
XUngrabPointer( display, CurrentTime );
XFlush( display );
barPos.right = b.right;
tims.end = tims.first + round( (b.right - traceBox.left) * tmp );
tims.steps = tims.end - tims.start;
}
/*
* Move the scrollbar left or right, always within the scrollbar bounds.
*/
private void MoveBar( x )
Coord x;
{
XEvent ev;
Coord width, handle;
Coord top, height;
float tmp;
TimeType maxTime, t1, t2;
maxTime = max( tims.last, tims.end );
if( maxTime <= tims.first )
return;
tmp = (float)(maxTime - tims.first) / (traceBox.right - traceBox.left);
top = barPos.top + 1;
height = barPos.bot - barPos.top - 1; /* bot - top - 1 - 1 + 1 */
width = barPos.right - barPos.left + 1;
if( x >= barPos.left and x <= barPos.right )
handle = x - barPos.left;
else if( (x > barPos.right) and (x + width - 1 > traceBox.right) )
handle = x + width - traceBox.right - 1;
else
handle = 0;
FillAREA( window, barPos.left, top, width, height, gcs.gray );
FillAREA( window, x - handle, top, width, height, gcs.white );
GrabMouse( window, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
None );
UpdateTimes( tims.start, tims.end ); /* initialize it */
do
{
XNextEvent( display, &ev );
if( ev.type != MotionNotify and ev.type != ButtonRelease )
continue;
FillAREA( window, x - handle, top, width, height, gcs.gray );
x = (ev.type == MotionNotify) ? ev.xmotion.x : ev.xbutton.x;
if( x - handle + width - 1 > traceBox.right )
{
if( x > traceBox.right )
x = traceBox.right;
handle = x - (traceBox.right - width + 1);
}
else if( x - handle < traceBox.left )
{
if( x < traceBox.left )
x = traceBox.left;
handle = x - traceBox.left;
}
FillAREA( window, x - handle, top, width, height, gcs.white );
t1 = round( (x - handle - traceBox.left) * tmp ) + tims.first;
t2 = t1 + tims.steps;
UpdateTimes( t1, t2 );
}
while( ev.type != ButtonRelease );
XUngrabPointer( display, CurrentTime );
XFlush( display );
barPos.left = x - handle;
barPos.right = x - handle + width - 1;
tims.start = round( (barPos.left - traceBox.left) * tmp ) + tims.first;
tims.end = tims.start + tims.steps;
}
/*
* Scroll left by 'hpages' half-pages.
*/
private void MoveLeft( hpages )
int hpages;
{
TimeType start;
start = tims.start - (hpages * tims.steps) / 2;
if( start < tims.first )
start = tims.first;
if( start == tims.start )
return;
tims.start = start;
tims.end = start + tims.steps;
RedrawTimes();
UpdateScrollBar();
DrawTraces( start, tims.end );
}
/*
* Scroll right by 'hpages' half-pages.
*/
private void MoveRight( hpages )
int hpages;
{
TimeType start;
start = tims.start + (hpages * tims.steps) / 2;
if( (start >= tims.last) or (start == tims.start) or
(start + tims.steps >= max_time ) )
return;
tims.start = start;
tims.end = start + tims.steps;
RedrawTimes();
UpdateScrollBar();
DrawTraces( start, tims.end );
}